{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "目录\n",
    "\n",
    "* [逻辑斯蒂回归](#逻辑斯蒂回归)\n",
    "* [加正则项的逻辑斯蒂回归](#加正则项的逻辑斯蒂回归)\n",
    "\n",
    "# 逻辑斯蒂回归"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "from scipy.optimize import minimize\n",
    "from sklearn.preprocessing import PolynomialFeatures"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "手动实现sigmoid函数"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [],
   "source": [
    "def sigmoid(z):\n",
    "    return 1./(1+np.exp(-z))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "手动实现损失函数的计算"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [],
   "source": [
    "# 计算损失函数\n",
    "def compute_loss(theta, X, y):\n",
    "    if np.ndim(theta) == 1:\n",
    "        theta = theta[:, np.newaxis]\n",
    "    z_x = X.dot(theta) # h=θ^T dot X=θ0*x0+θ1*x1\n",
    "    # print(z_x.shape) # (100,3)x(3,1)=>(100,1)\n",
    "    h_x = sigmoid(z_x) # =>(100,1)\n",
    "\n",
    "    m = y.size # 100，用于对loss求平均\n",
    "    J_loss = -1./m * (np.log(h_x).T.dot(y) + np.log(1-h_x).T.dot(1-y)) # =>(1,1)\n",
    "    if np.isnan(J_loss):\n",
    "        return np.inf\n",
    "    return J_loss[0][0]"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "加载数据\n",
    "\n",
    "数据集简要说明\n",
    "\n",
    "多元变量（二元），数据共有3列。\n",
    "\n",
    "前2列表示2个exam score，由2个考试分数共同决定该条样本是“通过考试”还是“没通过”考试\n",
    "\n",
    "第3列0表示没通过，1表示通过"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data shape: (100, 3)\n",
      "[[34.62365962 78.02469282  0.        ]\n",
      " [30.28671077 43.89499752  0.        ]\n",
      " [35.84740877 72.90219803  0.        ]\n",
      " [60.18259939 86.3085521   1.        ]\n",
      " [79.03273605 75.34437644  1.        ]]\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制数据点，便于查看数据分布\n",
    "def plot_data(data, label_pos, label_neg, axes=None):\n",
    "    # 获取正负样本的index\n",
    "    pos = data[:,2] == 1\n",
    "    neg = data[:,2] == 0\n",
    "\n",
    "    if axes is None:\n",
    "        axes = plt.gca()\n",
    "\n",
    "    axes.scatter(data[pos][:,0], data[pos][:,1], marker='+', c='k', s=60, linewidth=2, label=label_pos)\n",
    "    axes.scatter(data[neg][:,0], data[neg][:,1], c='y', s=60, linewidth=2, label=label_neg)\n",
    "    axes.legend()\n",
    "\n",
    "cwd = '/home/xijian/pycharm_projects/Magic-NLPer/MachineLearning/'\n",
    "data_dir = cwd+'LogisticRegression逻辑斯蒂回归/data/'\n",
    "\n",
    "data = np.loadtxt(data_dir+'data1.txt', delimiter=',')\n",
    "print('data shape:', data.shape) # (100,3)\n",
    "print(data[:5])\n",
    "plot_data(data, 'y=1', 'y=0')"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "查看一下$\\theta$ =[0, 0]时的loss："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.         34.62365962 78.02469282]\n",
      " [ 1.         30.28671077 43.89499752]\n",
      " [ 1.         35.84740877 72.90219803]\n",
      " [ 1.         60.18259939 86.3085521 ]\n",
      " [ 1.         79.03273605 75.34437644]] (100, 3)\n",
      "[[0.]\n",
      " [0.]\n",
      " [0.]\n",
      " [1.]\n",
      " [1.]] (100, 1)\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'compute_loss' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[0;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "\u001B[0;32m<ipython-input-3-4a822f83886c>\u001B[0m in \u001B[0;36m<module>\u001B[0;34m\u001B[0m\n\u001B[1;32m      5\u001B[0m \u001B[0mprint\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0my\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;36m5\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0my\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mshape\u001B[0m\u001B[0;34m)\u001B[0m \u001B[0;31m# (100,1)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m      6\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m----> 7\u001B[0;31m \u001B[0mloss\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mcompute_loss\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0marray\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;36m0\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;36m0\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;36m0\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mX\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0my\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m      8\u001B[0m \u001B[0mprint\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'\\nloss:'\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mloss\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n",
      "\u001B[0;31mNameError\u001B[0m: name 'compute_loss' is not defined"
     ]
    }
   ],
   "source": [
    "# 把θ0与x0=[1,1,...,1] 与特征x1,x2,..一起组成一个大X\n",
    "X = np.c_[np.ones(data.shape[0]), data[:,0:2]]\n",
    "print(X[:5], X.shape) # (100, 3)\n",
    "y = np.c_[data[:,2]]\n",
    "print(y[:5], y.shape) # (100,1)\n",
    "\n",
    "loss = compute_loss(np.array([[0],[0],[0]]), X, y)\n",
    "print('\\nloss:', loss)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "手动实现梯度计算"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3, 1)\n",
      "loss: 0.6931471805599453\n",
      "grad: [ -0.1        -12.00921659 -11.26284221]\n"
     ]
    }
   ],
   "source": [
    "# 计算梯度\n",
    "def compute_gradient(theta, X, y):\n",
    "    if np.ndim(theta) == 1:\n",
    "        theta = theta[:, np.newaxis]\n",
    "    # 计算model输出\n",
    "    z_x = X.dot(theta) # θ^T dot X=θ0*x0+θ1*x1\n",
    "    # print(z_x.shape) # (100,3)x(3,1)=>(100,1)\n",
    "    h_x = sigmoid(z_x) # =>(100,1)\n",
    "\n",
    "    m = y.size # 100 对应loss中求平均时的m\n",
    "\n",
    "    # 计算梯度并更新参数 X.T.dot(h_x-y):(3,100)x(100,1)=>(3,1)\n",
    "    grad = 1./m * X.T.dot(h_x-y) # (3,1)\n",
    "    return grad.flatten() # (3,)\n",
    "\n",
    "\n",
    "initial_theta = np.zeros(X.shape[1]) # (3,)\n",
    "initial_theta = initial_theta[:, np.newaxis] # (3,1)\n",
    "print(initial_theta.shape) # (3,1)\n",
    "\n",
    "loss = compute_loss(initial_theta, X, y)\n",
    "grad = compute_gradient(initial_theta, X, y)\n",
    "\n",
    "print('loss:', loss)\n",
    "print('grad:', grad)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "使用梯度下降求解参数，利用scipy.optimize.minimize()函数，指定最小化的目标即损失函数的计算，\n",
    "然后是梯度的计算，优化参数theta，输入输出(X, y)，即可实现最小化损失函数。"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:10: RuntimeWarning: divide by zero encountered in log\n",
      "  # Remove the CWD from sys.path while we load stuff.\n",
      "/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:10: RuntimeWarning: divide by zero encountered in log\n",
      "  # Remove the CWD from sys.path while we load stuff.\n"
     ]
    },
    {
     "data": {
      "text/plain": "      fun: 0.2034977015895099\n hess_inv: array([[ 2.85339493e+03, -2.32908823e+01, -2.27416470e+01],\n       [-2.32908823e+01,  2.04489131e-01,  1.72969525e-01],\n       [-2.27416470e+01,  1.72969525e-01,  1.96170322e-01]])\n      jac: array([-2.68557620e-09,  4.36433485e-07, -1.39671757e-06])\n  message: 'Optimization terminated successfully.'\n     nfev: 34\n      nit: 25\n     njev: 30\n   status: 0\n  success: True\n        x: array([-25.16131634,   0.2062316 ,   0.20147143])"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from scipy.optimize import minimize\n",
    "res = minimize(compute_loss, initial_theta, args=(X,y),\n",
    "               jac=compute_gradient, options={'maxiter':400})\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "theta: [-25.16131634   0.2062316    0.20147143] (3,)\n"
     ]
    }
   ],
   "source": [
    "# 查看最后优化得到的参数theta的值\n",
    "final_updated_theta = res.x\n",
    "print('theta:', final_updated_theta, final_updated_theta.shape) # (3,)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "根据求解出的参数$\\theta$绘制出决策边界："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "data": {
      "text/plain": "<matplotlib.legend.Legend at 0x7f371f824cf8>"
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制决策边界\n",
    "# 边界：\n",
    "x1_min, x1_max = X[:,1].min(), X[:,1].max() # 注意X[0]是常数列[1,1,...,1]\n",
    "x2_min, x2_max = X[:,2].min(), X[:,2].max()\n",
    "xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max)) # 生成网格坐标\n",
    "# print(xx1.shape, xx2.shape) # (50, 50) (50, 50)\n",
    "XX = np.c_[np.ones(xx1.ravel().shape[0]), xx1.ravel(), xx2.ravel()]\n",
    "# print(XX.shape) # (2500, 3)\n",
    "z_x = XX.dot(final_updated_theta) # (2500, 3)x(3,)=>(2500,)\n",
    "h_x = sigmoid(z_x)\n",
    "h_x = h_x.reshape(xx1.shape) # (50,50)\n",
    "# print(h_x.shape)\n",
    "plt.contour(xx1, xx2, h_x, [0.5], linewidths=1, colors='b') # 决策边界\n",
    "\n",
    "plot_data(data, 'y=1', 'y=0') # # 样本数据点\n",
    "plt.legend(loc=1)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 加正则项的逻辑斯蒂回归\n",
    "\n",
    "加正则项的逻辑斯蒂回归的损失函数手动实现"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [],
   "source": [
    "# 计算损失函数\n",
    "def compute_loss_reg(theta, reg, *args):\n",
    "    if np.ndim(theta) == 1:\n",
    "        theta = theta[:, np.newaxis] # (28,)=>(28,1)\n",
    "    XX, y = args\n",
    "    z_x = XX.dot(theta) # h=θ^T dot X=θ0*x0+θ1*x1\n",
    "    # print(z_x.shape) # (118,28)x(28,1)=>(118,1)\n",
    "    h_x = sigmoid(z_x) # =>(118,1)\n",
    "\n",
    "    m = y.size # 118 用于求平均损失\n",
    "    J_loss = -1./m * (np.log(h_x).T.dot(y) + np.log(1-h_x).T.dot(1-y)) # =>(1,1)\n",
    "    # 注意：正则项的求和中j是从1开始的，而不是0，因为约束的是特征，而\\theta_0对应的是x_0=1常数项\n",
    "    reg_item = reg/(2.*m) * np.sum(np.square(theta[:,0][1:]))\n",
    "    J_loss = J_loss + reg_item\n",
    "    if np.isnan(J_loss):\n",
    "        return np.inf\n",
    "    return J_loss[0][0]"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "加正则项的梯度计算的手动实现"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [],
   "source": [
    "# 计算梯度\n",
    "def compute_gradient_reg(theta, reg, *args):\n",
    "    if np.ndim(theta) == 1:\n",
    "        theta = theta[:, np.newaxis] # (28,)=>(28,1)\n",
    "    XX, y = args\n",
    "    # 计算model输出\n",
    "    z_x = XX.dot(theta) # θ^T dot X=θ0*x0+θ1*x1\n",
    "    # print(z_x.shape) # (118,28)x(28,1)=>(118,1)\n",
    "    h_x = sigmoid(z_x) # =>(118,1)\n",
    "\n",
    "    m = y.size # 118 对应于平均损失中的m\n",
    "\n",
    "    # 计算梯度并更新参数 X.T.dot(h_x-y):(28,118)x(118,1)=>(28,1)\n",
    "    grad = 1./m * XX.T.dot(h_x-y) # (28,1)\n",
    "\n",
    "    reg_item = reg/m * np.r_[ [[0]], theta[1:] ] # (1,1) 行拼接 (27,1)=>(28,1)\n",
    "    grad = grad + reg_item # (28,1)\n",
    "    return grad.flatten() # (28,)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "加载数据\n",
    "\n",
    "数据集简要说明\n",
    "\n",
    "多元变量（二元），数据共有3列。\n",
    "\n",
    "前2列表示2个Microchip Test的值，由2个测试结果共同决定该芯片是“通过”还是“没通过”测试\n",
    "\n",
    "第3列0表示没通过，1表示通过\n",
    "\n",
    "数据分布是非线性的"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data shape: (118, 3)\n",
      "[[ 0.051267  0.69956   1.      ]\n",
      " [-0.092742  0.68494   1.      ]\n",
      " [-0.21371   0.69225   1.      ]\n",
      " [-0.375     0.50219   1.      ]\n",
      " [-0.51325   0.46564   1.      ]]\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data2 = np.loadtxt(data_dir+'data2.txt', delimiter=',')\n",
    "print('data shape:', data2.shape) # (100,3)\n",
    "print(data2[:5])\n",
    "plot_data(data2, 'y=1', 'y=0')"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "可见该数据不是直接线性可分的，不能直接使用逻辑斯蒂回归。考虑在“线性回归原理小结”中提到“多项式回归”，\n",
    "这里使用“多项式特征”（sklearn.preprocessing.PolynomialFeatures）对原始数据X XX进行特征转化，对转化后的数据X ′ X'X\n",
    "′再使用逻辑斯蒂回归。由于数据比之前的复杂，这次便可在学习时加入正则项以避免过拟合。"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(118, 2) (118, 1)\n",
      "(28, 1)\n",
      "loss: 0.6931471805599454\n",
      "grad: [8.47457627e-03 1.87880932e-02 7.77711864e-05 5.03446395e-02\n",
      " 1.15013308e-02 3.76648474e-02 1.83559872e-02 7.32393391e-03\n",
      " 8.19244468e-03 2.34764889e-02 3.93486234e-02 2.23923907e-03\n",
      " 1.28600503e-02 3.09593720e-03 3.93028171e-02 1.99707467e-02\n",
      " 4.32983232e-03 3.38643902e-03 5.83822078e-03 4.47629067e-03\n",
      " 3.10079849e-02 3.10312442e-02 1.09740238e-03 6.31570797e-03\n",
      " 4.08503006e-04 7.26504316e-03 1.37646175e-03 3.87936363e-02]\n"
     ]
    }
   ],
   "source": [
    "X = data2[:, 0:2]\n",
    "y = np.c_[data2[:,2]]\n",
    "print(X.shape, y.shape) # (118, 2) (118, 1)\n",
    "\n",
    "poly = PolynomialFeatures(6) # 最高次项为6次\n",
    "XX = poly.fit_transform(X) # X是有2个特征，XX有28个特征（含组合特征）\n",
    "XX.shape # (118, 28)\n",
    "# 0次项：1个，1次项：2个，2次项：3个（x1^2,x2^2,x1x2），3次项：4个\n",
    "# 4次项：5个，5次项：6个，6次项：7个，一共28个特征\n",
    "\n",
    "initial_theta = np.zeros(XX.shape[1]) # (28,)\n",
    "initial_theta = initial_theta[:, np.newaxis]\n",
    "print(initial_theta.shape) # (28,1)\n",
    "\n",
    "loss = compute_loss_reg(initial_theta, 1, XX, y)\n",
    "grad = compute_gradient_reg(initial_theta, 1, XX, y)\n",
    "\n",
    "print('loss:', loss)\n",
    "print('grad:', grad)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "绘制决策边界，并查看不同的正则化项系数，对于决策边界的影响\n",
    "\n",
    "- lambda = 0 : 就是没有正则化，此时会容易过拟合\n",
    "- lambda = 1 : 合适的正则化项系数\n",
    "- lambda = 100 : 正则化项太激进，导致基本没拟合出决策边界"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3,)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:2: RuntimeWarning: overflow encountered in exp\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 1224x360 with 3 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 预测\n",
    "def predict(theta, X, threshold=0.5):\n",
    "    z_x = X.dot(theta) # (b,3)x(3,1)=>(b,1)\n",
    "    h_x = sigmoid(z_x) # (b,1)\n",
    "    pred = h_x >= threshold\n",
    "    return pred.astype('int') # (b,1) b个样本的预测结果\n",
    "\n",
    "\n",
    "fig, axes = plt.subplots(1, 3, sharey=True, figsize=(17,5))\n",
    "print(axes.shape) # (3,)\n",
    "\n",
    "lambda_list = [0., 1., 100.]\n",
    "for i,C in enumerate(lambda_list):\n",
    "    # 最小化损失\n",
    "    res2 = minimize(compute_loss_reg, initial_theta, args=(C,XX,y),\n",
    "               jac=compute_gradient_reg, options={'maxiter':3000})\n",
    "    final_updated_theta = res2.x # (28,)\n",
    "    # print('theta:', final_updated_theta.shape) # (28,)\n",
    "\n",
    "    # 计算准确率 XX:(118, 28) y:(118, 1) theta:=>(28,1)\n",
    "    pred = predict(final_updated_theta.reshape(-1,1), XX) # (118,1)\n",
    "    # print(pred.shape) # (118,1)\n",
    "    accuracy = 100. * sum(pred.ravel() == y.ravel()) / y.size\n",
    "\n",
    "    # 绘制原始数据分布\n",
    "    plot_data(data2, 'y=1', 'y=0', axes=axes.flatten()[i])\n",
    "\n",
    "    # 绘制决策边界 X:(118,2) y:(118,1)\n",
    "    # 边界：\n",
    "    x1_min, x1_max = X[:,0].min(), X[:,0].max() # 注意这里的X不含常数列[1,1,...,1]\n",
    "    x2_min, x2_max = X[:,1].min(), X[:,1].max()\n",
    "    xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max)) # 生成网格坐标\n",
    "    # print(xx1.shape, xx2.shape) # (50, 50) (50, 50)\n",
    "    X_ = np.c_[xx1.ravel(), xx2.ravel()]\n",
    "    # print(X_.shape) # (2500,2) # 没算常数列\n",
    "\n",
    "    XX_ = poly.fit_transform(X_) # (2500,28)\n",
    "    # print(XX_.shape) # (2500,28)\n",
    "    z_x = XX_.dot(final_updated_theta) # (2500, 28)x(28,)=>(2500,)\n",
    "    h_x = sigmoid(z_x) # (2500,)\n",
    "    h_x = h_x.reshape(xx1.shape) # (50,50)\n",
    "    #print(h_x.shape) # (50,50)\n",
    "\n",
    "    axes.flatten()[i].contour(xx1, xx2, h_x, [0.5], linewidths=1, colors='g') # 决策边界\n",
    "    # 设置标题\n",
    "    axes.flatten()[i].set_title('Train accuracy {:.2f}% with Lambda = {}'.format(accuracy, C))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}